#include "gpu_render.hpp"
#ifndef __SYNTHESIS__ // 仅在 C 仿真时包含 iostream
#include <iostream>
#endif

void GPU_Render(
    ddr_word_t* params_buffer_base_addr,
    const ap_uint<16> num_triangles_to_process,
    const ap_uint<11> max_x_res,
    const ap_uint<11> max_y_res,
    zbuffer_ddr_word_t* zbuffer_ddr_read_base_addr,
    zbuffer_ddr_word_t* zbuffer_ddr_write_base_addr,
    color_ddr_word_t* framebuffer_ddr_base_addr,
    ap_uint<32>& total_fragments_generated,
    ap_uint<32>& total_write_ops_processed
) {
    // --- 顶层 S_AXILITE 接口声明 ---
    #pragma HLS INTERFACE s_axilite port=params_buffer_base_addr bundle=ctrl_s_axilite
    #pragma HLS INTERFACE s_axilite port=num_triangles_to_process bundle=ctrl_s_axilite
    #pragma HLS INTERFACE s_axilite port=max_x_res bundle=ctrl_s_axilite
    #pragma HLS INTERFACE s_axilite port=max_y_res bundle=ctrl_s_axilite
    #pragma HLS INTERFACE s_axilite port=zbuffer_ddr_read_base_addr bundle=ctrl_s_axilite
    #pragma HLS INTERFACE s_axilite port=zbuffer_ddr_write_base_addr bundle=ctrl_s_axilite
    #pragma HLS INTERFACE s_axilite port=framebuffer_ddr_base_addr bundle=ctrl_s_axilite
    #pragma HLS INTERFACE s_axilite port=total_fragments_generated bundle=ctrl_s_axilite
    #pragma HLS INTERFACE s_axilite port=total_write_ops_processed bundle=ctrl_s_axilite
    #pragma HLS INTERFACE s_axilite port=return bundle=ctrl_s_axilite

    // --- M_AXI 接口声明 ---
    // !!! 修改此处：将 depth 从 4096 增加到 22000 !!!
    #pragma HLS INTERFACE m_axi port=params_buffer_base_addr    offset=slave bundle=m_axi_gmem_params_read   max_read_burst_length=256 latency=60 num_read_outstanding=32 depth=22000 
    #pragma HLS INTERFACE m_axi port=zbuffer_ddr_read_base_addr  offset=slave bundle=m_axi_gmem_zb_read      max_read_burst_length=256 latency=60 num_read_outstanding=32 depth=524288
    #pragma HLS INTERFACE m_axi port=zbuffer_ddr_write_base_addr offset=slave bundle=m_axi_gmem_zb_write     max_write_burst_length=256 latency=60 num_write_outstanding=32 depth=524288
    #pragma HLS INTERFACE m_axi port=framebuffer_ddr_base_addr offset=slave bundle=m_axi_gmem_fb_write max_read_burst_length=256 max_write_burst_length=256 latency=60 num_read_outstanding=32 num_write_outstanding=32 depth=524288

    // 启用 DATAFLOW 优化，将各个子模块并行化
    #pragma HLS DATAFLOW

    // --- 内部 Stream 声明 ---
    // 连接 PBIRSM -> HR
    hls::stream<raster_params_packet_fixed> pbirsm_to_hr_stream("pbirsm_to_hr_stream");
    // 原始 HR 模块中的 stream 深度为 2048。现在 HR 内部拆分，这个流可以减小。
    // 因为 hr_setup 只需要缓冲少数几个三角形参数。
    #pragma HLS STREAM variable=pbirsm_to_hr_stream depth=32 

    // 连接 HR -> PDTD
    hls::stream<pixel_fragment_packet_fixed> hr_to_pdtd_stream("hr_to_pdtd_stream");
    // 由于 HR 内部现在逐行生成像素，hr_to_pdtd_stream 不再需要缓冲整个三角形，只需缓冲几行的像素即可。
    #pragma HLS STREAM variable=hr_to_pdtd_stream depth=2048 // 保持2048，以便在hr_pixel_generator和pdtd之间有足够的弹性

    // 连接 PDTD -> DDR_Write_Engine
    hls::stream<ddr_write_packet_fixed> pdtd_to_dwe_stream("pdtd_to_dwe_stream");
    #pragma HLS STREAM variable=pdtd_to_dwe_stream depth=2048

    // 用于将 HR 的片段计数传输给 PDTD (现在由 hr_pixel_generator 写入)
    hls::stream<ap_uint<32>> hr_fragment_count_to_pdtd_stream("hr_fragment_count_to_pdtd_stream");
    #pragma HLS STREAM variable=hr_fragment_count_to_pdtd_stream depth=2

    // 用于将 PDTD 的有效片段计数传输给 DWE
    hls::stream<ap_uint<32>> pdtd_valid_fragments_count_to_dwe_stream("pdtd_valid_fragments_count_to_dwe_stream");
    #pragma HLS STREAM variable=pdtd_valid_fragments_count_to_dwe_stream depth=2

    // --- 实例化并连接子模块 ---

    // 1. Parameter Buffer Interface and Raster Setup Manager (PBIRSM)
    parameter_buffer_interface_and_raster_setup(
        params_buffer_base_addr,
        pbirsm_to_hr_stream,
        num_triangles_to_process
    );

    // 2. Hardware Rasterizer (HR) - 内部现在是 DATAFLOW 的子模块
    // total_fragments_generated 是 HR 模块最终输出到顶层的 S_AXILITE 寄存器的值
    hardware_rasterizer(
        pbirsm_to_hr_stream,
        hr_to_pdtd_stream,
        max_x_res,
        max_y_res,
        num_triangles_to_process,
        total_fragments_generated, // HR 的实际输出片段数 (包括无效的)
        hr_fragment_count_to_pdtd_stream // 这个流现在用于 HR 内部子模块之间传递计数，最后再传给 PDTD
    );
    
    // 3. Pixel Depth Test & Dispatch (PDTD)
    pixel_depth_test_and_dispatch(
        hr_to_pdtd_stream,
        pdtd_to_dwe_stream,
        max_x_res,
        max_y_res,
        hr_fragment_count_to_pdtd_stream, // PDTD 从此流读取 HR 报告的片段总数
        pdtd_valid_fragments_count_to_dwe_stream
    );

    // 4. DDR_Write_Engine (DWE)
    ddr_write_engine(
        pdtd_to_dwe_stream,
        pdtd_valid_fragments_count_to_dwe_stream,
        max_x_res,
        max_y_res,
        zbuffer_ddr_read_base_addr,
        zbuffer_ddr_write_base_addr,
        framebuffer_ddr_base_addr,
        total_write_ops_processed
    );
}

